/**
 * Projekt do předmetu GJA - LATEX TABLE CREATOR
 *
 * Soubor: AttributiveCellRenderer.java
 *
 * @author Ondřej Kubal  <xkluba00@stud.fit.vutbr.cz>
 * @author Petr Šimon    <xsimon10@stud.fit.vutbr.cz>
 */

package table;

import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.border.*;
import border.*;

/**
 * Popisuje cell renderer <code>TableCellRenderer</code> pro buňky tabulky <code>JTable</code>.
 * Primárně je urřen pro spolupráci s <code>AttributiveCellTableModel</code>.
 * Jedná se o přestylovaný label <code>JLabel</code>.
 * Umožňuje zobrazovat individuální barvy/písmo/rámečky pro jednotlivé buňky v tabulce dle dat modelu.
 */
public class AttributiveCellRenderer extends JLabel
          implements TableCellRenderer
{
     protected Border noFocusBorder;
     
     /**
      * Konstruktor
      * Nastavení výchozího vzhledu.
      */
     public AttributiveCellRenderer()
     {
          noFocusBorder = BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(0, 0, 1, 1, Color.LIGHT_GRAY), BorderFactory.createEmptyBorder(2, 3, 2, 3));
          setOpaque(true);
          setBorder(noFocusBorder);
     }
     
     /**
      * Vrací konponentu pro vykreslení buňky
      * @param  table          vykreslovaná tabulka
      * @param  value          objekt vykreslované buňky
      * @param  isSelected     buňka je vybraná
      * @param  hasFocus       má fokus
      * @param  row            index řádku
      * @param  column         index sloupce
      */
     public Component getTableCellRendererComponent(JTable table, Object value,
               boolean isSelected, boolean hasFocus, int row, int column)
     {
          //parametry zobrazení
          Color foreground = null;
          Color background = null;
          Font font = table.getFont();
          Border border = null;
          int style = Font.PLAIN;
          
          
          //přístup k modelu
          TableModel model = table.getModel();
          
          
          //model může obsahovat paramety - nařteme je
          if (model instanceof AttributiveCellTableModel)
          {
               CellAttribute cellAtt = ((AttributiveCellTableModel)model).getCellAttribute();
               
               //načteme barvy
               if (cellAtt instanceof ColoredCell)
               {
                    foreground = ((ColoredCell)cellAtt).getForeground(row, column);
                    background = ((ColoredCell)cellAtt).getBackground(row, column);
               }
               
               //načteme písmo buňky
               this.setHorizontalAlignment(SwingConstants.LEFT);
               
               if (cellAtt instanceof CellFont)
               {
                    font = ((CellFont)cellAtt).getFont(row, column); //písmo
                    //styl
                    style = ((CellFont)cellAtt).getFontAtt(row, column) & (CellFont.FLAG_B | CellFont.FLAG_I);
                    
                    //zarovnání
                    if ((((CellFont)cellAtt).getFontAtt(row, column) & CellFont.FLAG_H_A1) == CellFont.FLAG_H_A1)
                    {
                         if ((((CellFont)cellAtt).getFontAtt(row, column) & CellFont.FLAG_H_A2) == CellFont.FLAG_H_A2)
                              this.setHorizontalAlignment(SwingConstants.RIGHT);
                         else
                              this.setHorizontalAlignment(SwingConstants.CENTER);
                    }
                    
                    if (font == null) font = table.getFont();
                    
                    //TT
                    if ((((CellFont)cellAtt).getFontAtt(row, column) & CellFont.FLAG_T) == CellFont.FLAG_T)
                         font = (new Font("monospaced", style, font.getSize()));
                    else
                         font = (new Font("serif", style, font.getSize()));
               }
               
               //rámeček buňky
               if (cellAtt instanceof CellBorder)
               {
                    border = ((CellBorder)cellAtt).getBorder(row, column);
               }
          }
          
          setFont(font);
          
          if (isSelected)   //buňka je vybraná
          {
               //spočítáme rámeček výběru -> není triviální vzhedem ke sloučení buněk
               int[] columns = table.getSelectedColumns();
               int[] rows    = table.getSelectedRows();
               
               int rowMax    = rows.length;
               int columnMax = columns.length;
               
               int nrow = row;
               int ncol = column;
               
               {
                    CellSpan cellAtt = (CellSpan)((AttributiveCellTableModel)model).getCellAttribute();
                    int row_offset = ((CellSpan) cellAtt).getSpan(nrow, ncol)[CellSpan.ROW];
                    int col_offset = ((CellSpan) cellAtt).getSpan(nrow, ncol)[CellSpan.COLUMN];
                    
                    //podíváme se na sloučené buňky
                    if (row_offset >= 1) nrow += row_offset - 1;
                    
                    if (col_offset >= 1) ncol += col_offset - 1;
               }
               
               Insets newInets = new Insets(0, 0, 0, 0);
               
               if (border != null)
                    if (border instanceof LinesBorder)
                    {
                         newInets = ((LinesBorder) border).getInnerThickness();
                    }
                    else
                    {
                         newInets = border.getBorderInsets(null);
                    }
                    
                    
               Insets oldInets = new Insets(2, 2, 2, 2); // zde se definují okraje oblasti !!!
               
               for (int i = rowMax - 1; i >= 0; i--)
                    if ((row == rows[i]) || (nrow == rows[i]))
                         for (int j = columnMax - 1; j >= 0; j--)
                              if ((column == columns[j]) || (ncol == columns[j]))
                              {
                                   if ((i == 0))            newInets.top    = oldInets.top;
                                   
                                   if ((j == 0))            newInets.left   = oldInets.left;
                                   
                                   if ((i == rowMax - 1))     newInets.bottom = oldInets.bottom;
                                   
                                   if ((j == columnMax - 1))  newInets.right  = oldInets.right;
                              }
                              
               setBorder(BorderFactory.createCompoundBorder(
                              BorderFactory.createMatteBorder(0, 0, 1, 1, Color.LIGHT_GRAY),
                              BorderFactory.createCompoundBorder(
                                   BorderFactory.createMatteBorder(newInets.top, newInets.left, newInets.bottom, newInets.right, Color.DARK_GRAY),
                                   BorderFactory.createEmptyBorder(2, 3, 2, 3)
                              )
                         )
                        );
                        
               setForeground((foreground != null) ? foreground : Color.BLACK);
               
               if (background != null)
               {
               
                    setBackground(background.darker());
               }
               else
                    setBackground(new Color(215, 220, 206));
                    
          }
          else   //obyčejná buňka
          {
               setBorder((border != null)     ? border      : noFocusBorder);
               setForeground((foreground != null) ? foreground  : Color.BLACK);
               setBackground((background != null) ? background  : Color.WHITE);
          }
          
          if (hasFocus)   //právě aktivní buňka (psaní
          {
               /*  setBorder(BorderFactory.createCompoundBorder(  //UIManager.getBorder("Table.focusCellHighlightBorder")
                              BorderFactory.createMatteBorder(0,0,1,1,Color.LIGHT_GRAY),
                              BorderFactory.createCompoundBorder(
                                 BorderFactory.createMatteBorder(2,2,2,2,Color.DARK_GRAY),
                                 BorderFactory.createEmptyBorder(2,3,2,3)
                              )
                           )
                          );*/
               if (table.isCellEditable(row, column))
               {
                    setForeground((foreground != null) ? foreground : UIManager.getColor("Table.focusCellForeground"));
                    setBackground((background != null) ? background  : UIManager.getColor("Table.focusCellBackground"));
               }
          }
          
          setText((value == null) ? "" : value.toString()); //data
          return this;
     }
}
